#include "sql.h"
#include "exceptions.h"
#include "useful_functions.h"
#include "converter.h"
#include "global_variables.h"

void sql::set_value(unsigned short index, const string &value, bool use_apostrophe) {
  if (value.find(';') != string::npos)
    throw sql_injection_exception(global_empty_string);

  string str_cnv;

  if (use_apostrophe == true) {
    converter::replace_all(value, "'", "\\'", str_cnv);
    str_cnv.insert(0, 1, '\'');
    str_cnv.append(1, '\'');
  } else
    converter::remove_all(value, ' ', str_cnv); // removing all spaces makes sure that no SQL injection can occur

  values[index] = str_cnv;
} // sql::set_value

void sql::set_null(unsigned short index) {
  values[index] = "<NULL>";
} // sql::set_null

string &sql::to_string(string &output) const {
  if (values.size() != (size_t) count_if(statement.begin(), statement.end(), is_question_mark))
    throw parameter_exception(global_empty_string);

  output = statement; // keeps the original statement untouched
  size_t i = output.length();

  for (map<unsigned short, string>::const_reverse_iterator it = values.rbegin(); it != values.rend(); ++it) {
    i = output.rfind('?', i - 1);

    if ((*it).second == "<NULL>" || (use_null == true && ((*it).second).empty() == true))
      output.replace(i, strlen("?"), "NULL"); // without '
    else
      output.replace(i, strlen("?"), (*it).second);

  } // for

  return output;
} // sql::to_string

sql::sql(const string &statement, bool use_null) : statement(statement), use_null(use_null) {
  // nothing to do
} // sql::sql

sql::~sql() {
  // nothing to do
} // sql::~sql
